今天是鐵人的第29天,要來使用Prophet來預測股票。
Prophet:為Facebook提供的套件,用來預測系統,主要用時間序來做分析。
架構如下
(圖片來源Url)
Modeling:建立時間序列的模型。這邊使用股票來做模型。
Forecast Evaluation:模型評估。
Surface Problems:呈現問題。
Visually Inspect Forecasts:以視覺化的方式呈現預測結果。
打開Anaconda Prompt看是否有安裝Prophet(使用「conda list」指令),沒有就執行
conda install -c conda-forge fbprophet
介紹底下的圖表之前先預先載入需要的套件
# basic
import numpy as np
import pandas as pd
# get data
import pandas_datareader as pdr
# visual
import matplotlib.pyplot as plt
%matplotlib inline
#time
import datetime as datetime
#Prophet
from fbprophet import Prophet
from sklearn import metrics
我們讀取以下股票
2492:華新科
start = datetime.datetime(2015,1,5)
df_2492 = pdr.DataReader('2492.TW', 'yahoo', start=start)
如果只是用單純的收盤價繪製圖表,之前也介紹過了,範例如下:
plt.style.use('ggplot')
df_2492['Adj Close'].plot(figsize=(12, 8))
new_df_df_2492['y'] = np.log(new_df_df_2492['y'])
# 定義模型
model = Prophet()
# 訓練模型
model.fit(new_df_df_2492)
# 建構預測集
future = model.make_future_dataframe(periods=365) #forecasting for 1 year from now.
# 進行預測
forecast = model.predict(future)
figure=model.plot(forecast)
其中黑色代表實際的值,請注意黑色只到今天這個日期,藍線代表的是預測值,而淡藍色的陰影區表示不確定性,未來時間距離越遠,不確定區域就會越來越大。
如果不考慮未來的不確定性,只有看預測和實際數據的最後800筆(一年252筆),只想看實際和預測之間的視覺差距。
df_2492_close = pd.DataFrame(df_2492['Adj Close'])
two_years = forecast.set_index('ds').join(df_2492_close)
two_years = two_years[['Adj Close', 'yhat', 'yhat_upper', 'yhat_lower' ]].dropna().tail(800)
two_years['yhat']=np.exp(two_years.yhat)
two_years['yhat_upper']=np.exp(two_years.yhat_upper)
two_years['yhat_lower']=np.exp(two_years.yhat_lower)
two_years[['Adj Close', 'yhat']].plot(figsize=(8, 6));
橘色是實際的股價,藍色是預測的股價,從圖來看可以知道實際的股價和預測的股價非常相近。
現在來計算實際的股價和預測股價的誤差
two_years_AE = (two_years.yhat - two_years['Adj Close'])
two_years_AE.describe()
# 輸出結果
count 800.000000
mean -1.451949
std 14.302471
min -88.053614
25% -2.389504
50% 0.129703
75% 2.074819
max 64.853188
dtype: float64
平均誤差了-1.451949,最大差別了64.853188,最小-88.053614
print ("MSE:",metrics.mean_squared_error(two_years.yhat, two_years['Adj Close']))
# 輸出結果
MSE: 206.41313426786152
MSE越接近0越好
print ("MAE:",metrics.mean_absolute_error(two_years.yhat, two_years['Adj Close']))
# 輸出結果
MAE: 7.052998896728383
看了一下誤差數,Prophet預測這個股票是算準確的,但參考文章的內容卻是說用來預測股票是不適合的XDD。
fig, ax1 = plt.subplots(figsize=(10, 8))
ax1.plot(two_years['Adj Close'])
ax1.plot(two_years.yhat)
ax1.plot(two_years.yhat_upper, color='black', linestyle=':', alpha=0.5)
ax1.plot(two_years.yhat_lower, color='black', linestyle=':', alpha=0.5)
ax1.set_title('華新科技實際和預測的誤差')
ax1.set_ylabel('Price')
ax1.set_xlabel('Date')
橘色是實際的價格,藍色是是預測的,上下限用灰色。除了2018年7月的時候波動性太大造成的預測比較不準外,其他其實都蠻相近的。
從這幾個分析來看Prophet比較一個月內的預測,時間拉得越長預測會越不準。
使用Prophet來預測股票
new_df_df_2492['y'] = np.log(new_df_df_2492['y'])
NameError: name 'new_df_df_2492' is not defined
這裡會報錯,想請問版大該怎麼改呢~謝謝你<(._.)>
https://github.com/lastsummer/learn_python_data_analysis/blob/master/06.stock/day29.ipynb 這裡有完整程式,在文章中沒有加上定義的程式碼。所以會出現not defined
謝謝回覆~